package com.luxk.dbt;

import java.util.ArrayList;

public class ExecBlockThreads extends ExecBlock {
	
	private int count = 1;
	private int repeat = -1;
	private int duration = 0;
	
	private WorkThread4Perf wthrs[] = null;
	
	public ExecBlockThreads(String name, ExecIF parent, MainContext mCtx) {
		super(name, parent, mCtx);
		this.name = name;
		this.parent = parent;
		this.mCtx = mCtx;
		
		this.result = new Result(this, name);
	}

	@Override
	public ExecIF duplicate(ExecIF parent) throws DBTException, DataException {
		throw new DBTException(
				this.getClass().getName() + " unsupport duplicate",
				this.line);
	}

	@Override
	public void prepareInternal() throws DBTException, DataException {

		if(this.count < 0 || this.count > 10000000)
			throw new DBTException("invalid thread count " + this.count);
				
		if(this.children == null || this.children.size() == 0)
			return;

		this.wthrs = new WorkThread4Perf[this.count];
		for(int i = 1; i < this.wthrs.length; i++) {
			this.wthrs[i] = new WorkThread4Perf(this.name, this.mCtx);
			this.wthrs[i].setDuration(this.duration);
			this.wthrs[i].setRepeat(this.repeat);
			ArrayList<ExecIF> temp = new ArrayList<ExecIF>();
			for(ExecIF e: this.children) {
				ExecIF dup = e.duplicate(this);
				dup.setName(e.getName() + "(#" + i + ")");
				this.addChild(dup);
				temp.add(dup);
			}
			this.wthrs[i].setExec(temp);
		}
		this.wthrs[0] = new WorkThread4Perf(this.name, this.mCtx);
		this.wthrs[0].setDuration(this.duration);
		this.wthrs[0].setRepeat(this.repeat);
		this.wthrs[0].setExec(this.children);		
	}
	
	@Override
	public void runInternal() throws DBTException {
		
		this.result.begin();
		
		// start work thread
		for(int i = 0; i < this.wthrs.length; i++) {
			this.wthrs[i].start();
		}

		this.result.setSuccess();
	}

	@Override
	public void cleanupInternal() throws DBTException {}
	
	public void setCount(int val) {
		this.count = val;
	}
	
	public int getCount() {
		return this.count;
	}
	
	public void setRepeat(int val) {
		this.repeat = val;
	}
	
	public int getRepeat() {
		return this.repeat;
	}

	public int getDuration() {
		return duration;
	}

	public void setDuration(int val) {
		this.duration = val;
	}
	
	public boolean isFinished() {
		boolean finished = true;
		
		for(int i = 0; i < this.wthrs.length; i++) {
			if(this.wthrs[i].isFinished()) {
				finished = false;
			}
		}
		
		return finished;
	}

}
